#pragma once

#include "Renderer/Shader.h"
#include <string>
#include "glm/glm.hpp"

typedef unsigned int GLenum ;

namespace Orange {

	class OpenGLShader : public Shader
	{
	public:
		OpenGLShader(const std::string& filepath);
		OpenGLShader(const std::string& name, const std::string& vertexShaderSrc, const std::string& fragmentShaderSrc);
	
		~OpenGLShader();

		void bind() override;
		void ubind() override;
		virtual void SetMat4(const std::string& name, const glm::mat4& mat) override;
		virtual void SetFloat(const std::string& name, const float value) override;
		virtual void SetFloat4(const std::string& name, const glm::vec4& mat) override;
		virtual void SetFloat3(const std::string& name, const glm::vec3& mat) override;
		virtual void SetInt(const std::string& name, const int value) override;
		virtual void SetIntArray(const std::string& name, int* value, uint32_t count) override;
		/// <summary>
		/// �ϴ� uniform ����
		/// </summary>
		void UploadUniformMat4f(const std::string& name, const glm::mat4& mat) override;
		void UploadUniform4f(const std::string& name, const glm::vec4& mat) override;
		void UploadUniform3f(const std::string& name, const glm::vec3& mat) override;
		void UploadUniform2f(const std::string& name, const glm::vec2& mat) override;
		void UploadUniform1f(const std::string& name, const float value) override;
		void UploadUniformInt(const std::string& name, const int value) override;
		void UploadUniformIntArray(const std::string& name, int* value, uint32_t count) ;
		const std::string& GetName() const override { return m_Name; };
	private:
		/// <summary>
		/// ��ȡ�ļ�Դ��
		/// </summary>
		/// <param name="filepath"></param>
		/// <returns></returns>
		std::string ReadFile(const std::string& filepath);
		/// <summary>
		/// Ԥ�����ļ�Դ�룬����ɫ��Դ�����
		/// </summary>
		/// <param name="source"></param>
		std::unordered_map<GLenum , std::string> PreProcess(const std::string& source);
		/// <summary>
		/// ������ɫ��Դ��
		/// </summary>
		void Compile(std::unordered_map<GLenum, std::string>& shaderSource);
		uint32_t m_RendererId;
		std::string m_Name;
	};
}